/*
 * 
 * LegendShop 多用户商城系统
 * 
 *  版权所有,并保留所有权利。
 * 
 */
package com.legendshop.oa.tag;

import java.util.List;
import java.util.Map;

import com.legendshop.oa.constants.CommonConfigPropertiesEnum;
import com.legendshop.oa.handler.impl.ContextServiceLocator;
import com.legendshop.util.AppUtils;
import com.legendshop.util.EnvironmentConfig;
import com.legendshop.util.SystemUtil;

/**
 * 图片路径计算器,根据是否使用oss来计算路径,统一在一个地方计算,方便修改.
 */
public class PhotoPathResolver {

	private static PhotoPathResolver instance = null;

	// 路径计算器,有阿里云,独立服务器和本地服务器3种实现方式
	private PhotoPathCalculator photoPathCalculator;

	// 图片的地址和图片前缀
	private String photoServerAndPhotoPathPrfix;
	
	// 图片的地址和缩略图前缀
	private String photoServerAndImagesPathPrfix;	
	
	// 阿里云的oss地址
	private String ossDomainName;

	private Map<String, List<Integer>> scaleList = null;

	/**
	 * 私有化构造函数
	 */
	private PhotoPathResolver() {
		String attachmentType = EnvironmentConfig.getInstance().getPropertyValue(CommonConfigPropertiesEnum.ATTACHMENT_TYPE);
		// 是否使用阿里云的oss
		if (PhotoPathEnum.OSS.name().equalsIgnoreCase(attachmentType)) {
			
			// 阿里云的oss地址
			ossDomainName = ResourcePathUtil.getOSSDomainName();
			if (AppUtils.isNotBlank(ossDomainName) && !ossDomainName.endsWith("/")) {
				// 加上后斜杠
				ossDomainName = ossDomainName + "/";
			}

			
			photoPathCalculator = new OSSPhotoPathCalculatorImpl();
		} else if (PhotoPathEnum.HTTP.name().equalsIgnoreCase(attachmentType)) {
			
			// 图片的地址和前缀
			photoServerAndPhotoPathPrfix = ResourcePathUtil.getPhotoServer() + ResourcePathUtil.getPhotoPathPrefix();

			if (AppUtils.isNotBlank(photoServerAndPhotoPathPrfix) && !photoServerAndPhotoPathPrfix.endsWith("/")) {
				// 加上后斜杠
				photoServerAndPhotoPathPrfix = photoServerAndPhotoPathPrfix + "/";
			}
			
			//缩略图的地址和前缀
			photoServerAndImagesPathPrfix = ResourcePathUtil.getPhotoServer() + ResourcePathUtil.getSmallImagePathPrefix();
			
			if (AppUtils.isNotBlank(photoServerAndImagesPathPrfix) && !photoServerAndImagesPathPrfix.endsWith("/")) {
				// 加上后斜杠
				photoServerAndImagesPathPrfix = photoServerAndImagesPathPrfix + "/";
			}
			
			photoPathCalculator = new PhotoPathCalculatorImpl();
		}else {
			// 图片的地址和前缀
			photoServerAndPhotoPathPrfix = SystemUtil.getContextPath() + ResourcePathUtil.getPhotoPathPrefix();
			if (AppUtils.isNotBlank(photoServerAndPhotoPathPrfix) && !photoServerAndPhotoPathPrfix.endsWith("/")) {
				// 加上后斜杠
				photoServerAndPhotoPathPrfix = photoServerAndPhotoPathPrfix + "/";
			}
			//缩略图的地址和前缀
			photoServerAndImagesPathPrfix =  SystemUtil.getContextPath() +  ResourcePathUtil.getSmallImagePathPrefix();
			if (AppUtils.isNotBlank(photoServerAndImagesPathPrfix) && !photoServerAndImagesPathPrfix.endsWith("/")) {
				// 加上后斜杠
				photoServerAndImagesPathPrfix = photoServerAndImagesPathPrfix + "/";
			}
			photoPathCalculator = new LocalPhotoPathCalculatorImpl();
		}

		// 图片规格
		scaleList = (Map<String, List<Integer>>) ContextServiceLocator.getInstance().getBean("scaleList");
	}

	/**
	 * 单例模式
	 * 
	 * @return
	 */
	public static PhotoPathResolver getInstance() {
		if (instance == null) {
			synchronized (PhotoPathResolver.class) {
				if (instance == null) {
					instance = new PhotoPathResolver();
				}
			}
		}

		return instance;
	}

	/**
	 * 根据图片服务器的配置获取路径
	 * 
	 * @param filePath
	 * @return
	 */
	public PhotoPathDto calculateFilePath(String filePath) {
		return photoPathCalculator.calculateFilePath(filePath);
	}
	
	/**
	 * 根据图片服务器的配置获取路径
	 * 
	 * @param filePath
	 * @return
	 */
	public PhotoPathDto calculateImagePath(String filePath, String scale) {
		return photoPathCalculator.calculateImagePath(filePath, scale);
	}


	/**
	 * 计算文件的前缀
	 * 
	 * @return
	 */
	public PhotoPathDto calculateContextPath() {
		return photoPathCalculator.calculateContextPath();
	}
	
	public PhotoPathDto calculateImageSuffixPath(String scale) {
		return photoPathCalculator.calculateImageSuffixPath(scale);
	}
	
	public PhotoPathDto calculateImagesPrefixPath(String scale) {
		return photoPathCalculator.calculateImagesPrefixPath(scale);
	}

	/**
	 * 计算路径
	 * 
	 * @author root
	 *
	 */
	interface PhotoPathCalculator {
		/**
		 * 计算文件路径
		 * 
		 * @param filePath
		 * @return
		 */
		public PhotoPathDto calculateFilePath(String filePath);

		/**
		 * 计算缩略图的前缀
		 * 
		 * @param filePath
		 * @return
		 */
		public PhotoPathDto calculateImagesPrefixPath(String scale);

		/**
		 * 计算缩略图的后缀
		 * 
		 * @param filePath
		 * @return
		 */
		public PhotoPathDto calculateImageSuffixPath(String scale);

		/**
		 * 计算缩略图文件路径
		 * 
		 * @param filePath
		 * @return
		 */
		public PhotoPathDto calculateImagePath(String filePath, String scale);

		/**
		 * 计算文件的前缀
		 * 
		 * @return
		 */
		public PhotoPathDto calculateContextPath();
	}

	/**
	 * http远程图片服务
	 *
	 */
	class PhotoPathCalculatorImpl implements PhotoPathCalculator {
		@Override
		public PhotoPathDto calculateFilePath(String filePath) {
			return new PhotoPathDto(PhotoPathEnum.HTTP, new StringBuilder(64).append(photoServerAndPhotoPathPrfix).append(filePath).toString());
		}

		@Override
		public PhotoPathDto calculateContextPath() {
			return new PhotoPathDto(PhotoPathEnum.HTTP, photoServerAndPhotoPathPrfix);
		}

		@Override
		public PhotoPathDto calculateImagePath(String filePath, String scale) {
			String imageFilePath = new StringBuilder(64).append(photoServerAndImagesPathPrfix).append(scale).append("/").append(filePath).toString();
			return new PhotoPathDto(PhotoPathEnum.HTTP, imageFilePath);
		}

		@Override
		public PhotoPathDto calculateImageSuffixPath(String scale) {
			return new PhotoPathDto(PhotoPathEnum.HTTP, "");
		}
		
		@Override
		public PhotoPathDto calculateImagesPrefixPath(String scale) {
			String imageFilePath = new StringBuilder(64).append(photoServerAndImagesPathPrfix).append(scale).append("/").toString();
			return new PhotoPathDto(PhotoPathEnum.HTTP, imageFilePath);
		}
	}
	
	/**
	 * Local本地图片服务
	 *
	 */
	class LocalPhotoPathCalculatorImpl implements PhotoPathCalculator {
		@Override
		public PhotoPathDto calculateFilePath(String filePath) {
			return new PhotoPathDto(PhotoPathEnum.LOCAL, new StringBuilder(64).append(photoServerAndPhotoPathPrfix).append(filePath).toString());
		}

		@Override
		public PhotoPathDto calculateContextPath() {
			return new PhotoPathDto(PhotoPathEnum.LOCAL, photoServerAndPhotoPathPrfix);
		}

		@Override
		public PhotoPathDto calculateImagePath(String filePath, String scale) {
			String imageFilePath = new StringBuilder(64).append(photoServerAndImagesPathPrfix).append(scale).append("/").append(filePath).toString();
			return new PhotoPathDto(PhotoPathEnum.LOCAL, imageFilePath);
		}
		
		@Override
		public PhotoPathDto calculateImageSuffixPath(String scale) {
			return new PhotoPathDto(PhotoPathEnum.LOCAL, "");
		}

		@Override
		public PhotoPathDto calculateImagesPrefixPath(String scale) {
			String imageFilePath = new StringBuilder(64).append(photoServerAndImagesPathPrfix).append(scale).append("/").toString();
			return new PhotoPathDto(PhotoPathEnum.LOCAL, imageFilePath);
		}
	}
	
	/**
	 * oss远程图片服务
	 *
	 */
	class OSSPhotoPathCalculatorImpl implements PhotoPathCalculator {
		@Override
		public PhotoPathDto calculateFilePath(String filePath) {
			return new PhotoPathDto(PhotoPathEnum.OSS, new StringBuilder(64).append(ossDomainName).append(filePath).toString());
		}

		@Override
		public PhotoPathDto calculateContextPath() {
			return new PhotoPathDto(PhotoPathEnum.OSS, ossDomainName);
		}

		@Override
		public PhotoPathDto calculateImagePath(String filePath, String scale) {
			List<Integer> scales = scaleList.get(scale);
			if (scales != null) {
				String param = "?x-oss-process=image/resize,m_fixed,h_" + scales.get(0) + ",w_" + scales.get(1);
				String path = new StringBuilder(64).append(ossDomainName).append(filePath).append(param).toString();
				return new PhotoPathDto(PhotoPathEnum.OSS, path);
			} else {
				String path = new StringBuilder(64).append(ossDomainName).append(filePath).toString();
				return new PhotoPathDto(PhotoPathEnum.OSS, path);
			}
		}
		
		@Override
		public PhotoPathDto calculateImageSuffixPath(String scale) {
			List<Integer> scales = scaleList.get(scale);
			if (scales != null) {
				String param = "?x-oss-process=image/resize,m_fixed,h_" + scales.get(0) + ",w_" + scales.get(1);
				return new PhotoPathDto(PhotoPathEnum.OSS, param);
			}
			return new PhotoPathDto(PhotoPathEnum.OSS, "");
		}

		/**
		 * oss的缩略图前缀是跟大图一样的
		 */
		@Override
		public PhotoPathDto calculateImagesPrefixPath(String scale) {
			return new PhotoPathDto(PhotoPathEnum.OSS, ossDomainName);
		}
	}





}
